package org.flintparticles.common.stage3d
{
	import flash.display.Stage;
	import flash.display.Stage3D;
	import flash.display3D.Context3D;
	import flash.display3D.Context3DTriangleFace;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	public class Stage3DManager extends EventDispatcher
	{
		private static var _instance:Stage3DManager;
		private static var _allowInstance:Boolean;
		private var _contextRequested:Boolean=false;
		private var _context3D:Context3D;
		private var _antialias:int=1;
		private var _stage:Stage
		private var _stage3D:Stage3D;
		private var _shaderProgramManager:ShaderProgramManager;
		public function Stage3DManager(stage : Stage,singletonInforcer:SingletonEnforcer)
		{
			if(!_allowInstance){
				throw new Error("Use Singleton.getInstance() instead of new keyword");
			}
			_stage=stage;
		}
		public static function getInstance(stage : Stage):Stage3DManager{
			if(_instance==null){
				_allowInstance=true;
				_instance=new Stage3DManager(stage,new SingletonEnforcer);
				_allowInstance=false;
			
			}else{
				trace("The Stage3DManager already exists");
			}
			return _instance;
		}
		
		public  function setStage3dByIndex(index:uint):void{
		  _stage3D= _stage.stage3Ds[index];
		  _stage3D.addEventListener(Event.CONTEXT3D_CREATE,onContextReady);
		  _stage3D.requestContext3D();
		  _contextRequested = true;
		}
		private function onContextReady(e:Event):void{
			_stage3D.removeEventListener(Event.CONTEXT3D_CREATE, onContextReady);
			if(_stage3D.context3D){
				_context3D=_stage3D.context3D;
				_context3D.setCulling(Context3DTriangleFace.BACK);
			//	_context3D.setDepthTest(false,Context3DCompareMode.GREATER);
				_context3D.enableErrorChecking = false;
				_context3D.configureBackBuffer(_stage.stageWidth,_stage.stageHeight,_antialias,false);
				//////////init the shader programs stock which will be accessed by the particle geometry during  runtime
				_shaderProgramManager=new ShaderProgramManager(_context3D);
				dispatchEvent(new Event("CONTEXT3D_READY"));///later substitute with a generic event
			}
		}

		public function get stage3D():Stage3D
		{
			return _stage3D;
		}

		public function get context3D():Context3D
		{
			return _context3D;
		}

		public function get antialias():int
		{
			return _antialias;
		}

		public function set antialias(value:int):void
		{
			_antialias = value;
		}

		public function get shaderProgramManager():ShaderProgramManager
		{
			return _shaderProgramManager;
		}


	}
}
class SingletonEnforcer {}